
package com.joysuch.wwyt.risk.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.api.dataaccess.DataAccessService;
import com.joysuch.wwyt.api.dataaccess.OrientationDataSyncService;
import com.joysuch.wwyt.bp.bean.BpBaseUserBean;
import com.joysuch.wwyt.bp.bean.safetyworkcert.BpWorkRiskDto;
import com.joysuch.wwyt.bp.entity.BpDepart;
import com.joysuch.wwyt.bp.entity.BpTaskList;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.bp.repository.BpTaskListDao;
import com.joysuch.wwyt.core.bean.SimpleListBean;
import com.joysuch.wwyt.core.bean.SimpleSelectListBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.RiskLevels;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiBusinessException;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.dataperm.annotation.EnableDataPermission;
import com.joysuch.wwyt.mh.service.MonitorPointDataWebSocketService;
import com.joysuch.wwyt.risk.bean.*;
import com.joysuch.wwyt.risk.entity.*;
import com.joysuch.wwyt.risk.entity.dsl.QRiskDistrict;
import com.joysuch.wwyt.risk.entity.vo.DistrictDeleteCheckVO;
import com.joysuch.wwyt.risk.enums.RiskPointStates;
import com.joysuch.wwyt.risk.repository.*;
import com.joysuch.wwyt.risk.service.*;
import com.joysuch.wwyt.risk.util.RiskPointUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RiskDistrictServiceImpl implements RiskDistrictService {
    private static final Logger logger = LoggerFactory.getLogger(RiskDistrictServiceImpl.class);
    @Autowired
    private BpTaskListDao taskListDao;
    @Autowired
    private RiskDistrictDao dao;
    @Autowired
    private BpDepartDao departDao;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;
    @Autowired
    private RiskEvaluationAlarmMesageService evaluationAlarmMessageService;
    @Autowired
    private RiskDistrictEvaluationService districtEvaluationService;
    @Autowired
    private RiskEvaluationRepoService riskEvaluationRepoService;
    @Autowired
    private DataAccessService dataAccessService;
    @Autowired
    private RiskPointDao riskPointDao;
    @Autowired
    private OrientationDataSyncService orientationDataSyncService;
    @Autowired
    private BaseConfigService baseConfigService;
    @Autowired
    private BaseTypeGroupItemDao baseTypeGroupItemDao;
    @Autowired
    private RiskPointEvaluationBusinessDao riskPointEvaluationBusinessDao;
    @Autowired
    private RiskEvaluationControlDao controlDao;
    @Autowired
    private MonitorPointDataWebSocketService monitorPointDataWebSocketService;
    @Autowired
    private RiskEvaluationControlService controlService;
    @Autowired
    private RiskEvaluationBusinessService riskEvaluationBusinessService;
    @Autowired
    private RiskEvaluationBusinessDao riskEvaluationBusinessDao;
    @Autowired
    private RiskPromiseCardDao riskPromiseCardDao;
    @Autowired
    private RiskEmergencyCardDao riskEmergencyCardDao;
    @Autowired
    private RiskShouldKnowCardDao riskShouldKnowCardDao;

    @Override
    @Transactional
    public void add(RiskDistrictSaveBean districtBean) throws Exception {
        Assert.isTrue(dao.countOfName(districtBean.getName()) == 0, String.format("名称[%s]已存在", districtBean.getName()));
        Assert.isTrue(dao.countOfCode(districtBean.getCode()) == 0, String.format("编号[%s]已存在", districtBean.getCode()));
        RiskDistrict riskDistrict = new RiskDistrict();
        if (StringUtils.isBlank(districtBean.getCode())) {
            districtBean.setCode(bizCodeGeneratorFacade.fengXianQuYu());
        }
        BeanUtils.copyProperties(districtBean, riskDistrict);
        if (!CollectionUtils.isEmpty(districtBean.getResponsibleUseBeanList())) {
            List<Long> repUserIdList = districtBean.getResponsibleUseBeanList().stream().map(SimpleListBean::getId).collect(Collectors.toList());
            riskDistrict.setResponsibleUser(JSON.toJSONString(repUserIdList));
        } else {
            riskDistrict.setResponsibleUser(null);
        }
        if (!CollectionUtils.isEmpty(districtBean.getAreaHelpersList())) {
            List<Long> repUserIdList = districtBean.getAreaHelpersList().stream().map(SimpleListBean::getId).collect(Collectors.toList());
            riskDistrict.setAreaHelpers(JSON.toJSONString(repUserIdList));
        } else {
            riskDistrict.setAreaHelpers(null);
        }
        riskDistrict.setRealTimeRiskLevel(districtBean.getRiskLevel().doubleValue());
        riskDistrict.setStableRiskLevel(districtBean.getRiskLevel());
        riskDistrict.setInvestiageRiskLevel(districtBean.getRiskLevel());
        RiskDistrict save = dao.save(riskDistrict);
        checkRiskDistrict(save);
        List<RiskDistrict> orList = new ArrayList<>();
        orList.add(save);
        orientationDataSyncService.riskDistrict(orList, "addArea");
        saveTaskList("区域风险评估", save);
        //调用数据接入接口
        dataAccessService.riskArea(Lists.newArrayList(save));
        monitorPointDataWebSocketService.getDistrictList(Lists.newArrayList(save), "ADD", Context.getCompanyCode(), Context.getCurrentTenantId());
    }

    private void saveTaskList(String module, RiskDistrict save) {
        // 添加代办事项
        BpTaskList bpTaskList = new BpTaskList();
        bpTaskList.setDataId(save.getId());
        bpTaskList.setState(1);
        bpTaskList.setModule(module);
        taskListDao.save(bpTaskList);
    }

    @Override
    @Transactional
    public void update(RiskDistrictSaveBean districtBean) throws Exception {
        Assert.isTrue(dao.countOfNameExcludeId(districtBean.getName(), districtBean.getId()) == 0,
                String.format("名称[%s]已存在", districtBean.getName()));
        Assert.isTrue(dao.countOfCodeExcludeId(districtBean.getCode(), districtBean.getId()) == 0,
                String.format("编号[%s]已存在", districtBean.getCode()));
        RiskDistrict riskDistrict = dao.findById(districtBean.getId()).get();
        Integer oldLevel = riskDistrict.getRiskLevel();
        if (riskDistrict == null) {
            return;
        }
        BeanUtils.copyProperties(districtBean, riskDistrict, "riskLevel");
        RiskEvaluationBusiness evaluationBusiness = riskEvaluationBusinessDao.findByRiskDistrictId(riskDistrict.getId());
        Date lastDate = riskPointEvaluationBusinessDao.getLastEvalDateByDistrictId(riskDistrict.getId());
        if (lastDate == null && evaluationBusiness == null) {
            riskDistrict.setRiskLevel(districtBean.getRiskLevel());
            riskDistrict.setRealTimeRiskLevel(districtBean.getRiskLevel().doubleValue());
            riskDistrict.setInvestiageRiskLevel(districtBean.getRiskLevel());
        }
        riskDistrict.setStableRiskLevel(districtBean.getRiskLevel());
        if (!CollectionUtils.isEmpty(districtBean.getResponsibleUseBeanList())) {
            List<Long> repUserIdList = districtBean.getResponsibleUseBeanList().stream().map(SimpleListBean::getId).collect(Collectors.toList());
            riskDistrict.setResponsibleUser(JSON.toJSONString(repUserIdList));
        } else {
            riskDistrict.setResponsibleUser(null);
        }
        if (!CollectionUtils.isEmpty(districtBean.getAreaHelpersList())) {
            List<Long> repUserIdList = districtBean.getAreaHelpersList().stream().map(SimpleListBean::getId).collect(Collectors.toList());
            riskDistrict.setAreaHelpers(JSON.toJSONString(repUserIdList));
        } else {
            riskDistrict.setAreaHelpers(null);
        }
        RiskDistrict save = dao.save(riskDistrict);
        checkRiskDistrict(save);
        List<RiskDistrict> orList = new ArrayList<>();
        orList.add(save);
        riskEvaluationBusinessService.editDistrictLevel(save, oldLevel, "区域划分");
        orientationDataSyncService.riskDistrict(orList, "alterArea");
        //monitorPointDataWebSocketService.getDistrictList(Lists.newArrayList(save), "UPDATE", Context.getCompanyCode(), Context.getCurrentTenantId());

    }

    private void checkRiskDistrict(RiskDistrict riskDistrict) {
        List<RiskDistrict> districts = dao.findByCode(riskDistrict.getCode());
        if (districts.size() > 1) {
            throw new IllegalArgumentException("区域编码已存在");
        }
    }

    @Override
    @EnableDataPermission
    public List<RiskDistrict> findByResponsibleDept() {
        return dao.findAll();
    }

    @Override
    @Transactional
    public Page<RiskDistrict> findByPage(Pageable page, RiskDistrictListSearchBean condition) {
        Predicate p = null;
        QRiskDistrict q = QRiskDistrict.riskDistrict;
        if (StringUtils.isNotBlank(condition.getNameOrCode())) {
            p = ExpressionUtils.or(q.code.contains(condition.getNameOrCode()),
                    q.name.contains(condition.getNameOrCode()));
        }
        if (StringUtils.isNotBlank(condition.getName())) {
            p = ExpressionUtils.and(p, q.name.like("%" + condition.getName() + "%"));
        }
        if (null != condition.getStatus() && 0 == condition.getStatus()) {
            p = ExpressionUtils.and(p, q.coordinates.isNull());
        } else if (null != condition.getStatus() && 1 == condition.getStatus()) {
            p = ExpressionUtils.and(p, q.coordinates.isNotNull());
        }
        if (condition.getType() != null) {
            BooleanExpression eq = q.type.eq(condition.getType());
            p = p == null ? eq : ExpressionUtils.and(p, eq);
        }
        if (condition.getDeptId() !=null){
            BooleanExpression eq = q.responsibleDept.eq(condition.getDeptId());
            p=ExpressionUtils.and(p,eq);
        }
        p = ExpressionUtils.and(p, ExpressionUtils.or(q.state.notIn(DataStateTypes.DELETE.getState()), q.state.isNull()));
        return p == null ? dao.findAll(page) : dao.findAll(p, page);
    }

    @Override
    public List<RiskDistrict> findAllHaveLocation() {
        return dao.findAllHaveLocation();
    }

    @Override
    public Long getNumForHaveLocation(Integer flag) {
        Predicate p = null;
        QRiskDistrict q = QRiskDistrict.riskDistrict;
        if (null != flag && 1 == flag) {
            p = ExpressionUtils.and(p, q.coordinates.isNotNull());
        }
        p = ExpressionUtils.and(p, ExpressionUtils.or(q.state.notIn(DataStateTypes.DELETE.getState()), q.state.isNull()));
        return dao.count(p);
    }

    @Override
    @Transactional
    public void delete(Long id) throws ApiBusinessException {
        RiskDistrict risk = dao.findById(id).orElseThrow(() -> new IllegalArgumentException("风险区域不存在"));
        DistrictDeleteCheckVO vo = checkDistrict(id);
        vo.setAreaName(risk.getName());
        vo.setAreaCode(risk.getCode());
        int totalNum = vo.getRiskPointNum() + vo.getPromiseCardNum() + vo.getEmergencyCardNum() + vo.getKnowCardNum();
        if (totalNum > 0) {
            throw new ApiBusinessException(Status.DELETE_CHECK_FAILED.getCode(), JSONObject.toJSONString(vo));
        }
        risk.setState(DataStateTypes.DELETE.getState());
        RiskDistrict save = dao.save(risk);
        List<RiskDistrict> orList = new ArrayList<>();
        orList.add(save);
        if (StringUtils.isNotBlank(save.getUniqueId()) && baseConfigService.checkIfSync()) {
            orientationDataSyncService.riskDistrict(orList, "deleteArea");
        }
        monitorPointDataWebSocketService.getDistrictList(Lists.newArrayList(risk), "HANDLE", Context.getCompanyCode(), Context.getCurrentTenantId());
    }

    private DistrictDeleteCheckVO checkDistrict(Long districtId) {
        DistrictDeleteCheckVO vo = new DistrictDeleteCheckVO();

        List<RiskPoint> pointList = riskPointDao.findByRiskDistrictId(districtId);
        // 风险分析单元数量
        vo.setRiskPointNum(!CollectionUtils.isEmpty(pointList) ? pointList.size() : 0);
        // 承诺卡数量
        int promiseCardNum = riskPromiseCardDao.countByRiskDistrictId(districtId);
        vo.setPromiseCardNum(promiseCardNum);
        // 应急卡数量
        int emergencyCardNum = riskEmergencyCardDao.countByRiskDistrictId(districtId);
        vo.setEmergencyCardNum(emergencyCardNum);
        // 应知卡数量
        int knowCardNum = riskShouldKnowCardDao.countByRiskDistrictId(districtId);
        vo.setKnowCardNum(knowCardNum);
        return vo;
    }

    @Override
    @Transactional
    public RiskDistrict findById(Long id) {
        return dao.findById(id).get();
    }

    @Override
    @Transactional
    public String findDistrictNameById(Long id) {
        RiskDistrict district = findById(id);
        return district == null ? "" : district.getName();
    }

    @Override
    @Transactional
    public Page<RiskDistrictStableRiskListBean> findByPage(Pageable page, RiskDistrictStableRiskListSearchBean search) {
        QRiskDistrict point = QRiskDistrict.riskDistrict;
        Predicate predicate = null;
        if (search.getNameOrCode() != null) {
            predicate = ExpressionUtils.or(point.name.like("%" + search.getNameOrCode() + "%"),
                    point.code.like("%" + search.getNameOrCode() + "%"));
        }
        if (search.getState() != null) {
            BooleanExpression eq = point.evaluationState.eq(search.getState());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        if (search.getRiskLevel() != null) {
            BooleanExpression eq = point.riskLevel.eq(search.getRiskLevel());
            predicate = predicate == null ? eq : ExpressionUtils.and(predicate, eq);
        }
        predicate = ExpressionUtils.and(predicate, ExpressionUtils.or(point.state.notIn(DataStateTypes.DELETE.getState()), point.state.isNull()));
        //
        Page<RiskDistrict> all = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        return PageDataUtils.convertPageData(all, new PageDataConvert<RiskDistrictStableRiskListBean, RiskDistrict>() {

            @Override
            public RiskDistrictStableRiskListBean convert(RiskDistrict f) {
                RiskDistrictStableRiskListBean bean = new RiskDistrictStableRiskListBean();
                bean.setId(f.getId());
                bean.setCode(f.getCode());
                bean.setName(f.getName());
                bean.setEvaluationYear(f.getLastEvaluationYear());
                if (f.getRiskDistrictEvaluation() != null) {
                    bean.setResponsibleDepartId(f.getRiskDistrictEvaluation().getResponsibleDepartId());
                    if (bean.getResponsibleDepartId() != null) {
                        BpDepart depart = departDao.getOne(f.getRiskDistrictEvaluation().getResponsibleDepartId());
                        if (depart != null) {
                            bean.setResponsibleDepartName(depart.getName());
                        }
                    }
                }
                bean.setRiskLevel(f.getRiskLevel());
                bean.setRiskLevelName(RiskLevels.findRiskLevelName(f.getRiskLevel()));
                bean.setState(f.getEvaluationState());
                bean.setType(f.getType());
                bean.setTypeName(baseTypeGroupItemDao.findNameById(f.getType()));
                //bean.setType(f.getType());
                return bean;
            }

        });
    }

    @Override
    @Transactional
    public Page<RiskDistrictEvaluationListBean> findDistrictEvluationByPage(Pageable page, Integer evaluationState) {
        // TODO 整理出每个单据的状态
        QRiskDistrict point = QRiskDistrict.riskDistrict;
        Predicate predicate = null;
        if (evaluationState != null) {
            predicate = point.evaluationState.eq(evaluationState);
        }
        //
        predicate = ExpressionUtils.and(predicate, ExpressionUtils.or(point.state.notIn(DataStateTypes.DELETE.getState()), point.state.isNull()));
        Page<RiskDistrict> all = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);
        return PageDataUtils.convertPageData(all, new PageDataConvert<RiskDistrictEvaluationListBean, RiskDistrict>() {

            @Override
            public RiskDistrictEvaluationListBean convert(RiskDistrict f) {
                RiskDistrictEvaluationListBean bean = new RiskDistrictEvaluationListBean();
                bean.setId(f.getId());
                bean.setName(f.getName());
                bean.setState(f.getEvaluationState());
                return bean;
            }

        });
    }

    @Override
    @Transactional
    public RiskDistrictStableRiskQueryBean findStableRiskEvaluationDetail(Long riskDisctrictId, boolean searchHistory) {
        RiskDistrict distrct = dao.findById(riskDisctrictId).get();
        RiskDistrictEvaluation evaluation = distrct.getRiskDistrictEvaluation();
        if (evaluation == null && searchHistory) {
            evaluation = districtEvaluationService.findLastestOfDistrict(riskDisctrictId);
        }
        if (evaluation == null) {
            RiskDistrictStableRiskQueryBean baseInfo = new RiskDistrictStableRiskQueryBean();
            baseInfo.setRiskDistrictId(distrct.getId());
            baseInfo.setCode(distrct.getCode());
            baseInfo.setRiskDistrictName(distrct.getName());
            baseInfo.setRiskLevel(distrct.getRiskLevel());
            baseInfo.setRiskLevelName(RiskLevels.findRiskLevelName(distrct.getRiskLevel()));
            return baseInfo;
        }
        return convert(distrct, evaluation);
    }

    private RiskDistrictStableRiskQueryBean convert(RiskDistrict distrct, RiskDistrictEvaluation evaluation) {
        RiskDistrictStableRiskQueryBean b = new RiskDistrictStableRiskQueryBean();
        b.setReviseLevel(evaluation.getReviseLevel());
        b.setRiskDistrictId(distrct.getId());
        b.setCode(distrct.getCode());
        b.setEvaluationOffice(evaluation.getEvaluationOffice());
        fillEvaluationOfficeName(b, evaluation.getEvaluationOffice());
        if (evaluation.getEvaluationTime() != null) {
            b.setEvaluationTime(SimpleDateFormatCache.getYmd().format(evaluation.getEvaluationTime()));
        }
        b.setEvaluationUserId(evaluation.getEvaluationUserId());
        b.setEvaluationUserName(baseUserDao.getBaseUserNameById(evaluation.getEvaluationUserId()));
        b.setRiskDistrictName(distrct.getName());
        b.setResponsibleDepartId(evaluation.getResponsibleDepartId());
        b.setResponsibleDepartName(departDao.findDepartNameById(evaluation.getResponsibleDepartId()));
        b.setResponsiblePersonId(evaluation.getResponsiblePersonId());
        b.setResponsiblePersonName(baseUserDao.getBaseUserNameById(evaluation.getResponsiblePersonId()));
        // 改为区域的风险等级
        b.setRiskLevel(distrct.getRiskLevel());
        b.setRiskLevelName(RiskLevels.findRiskLevelName(distrct.getRiskLevel()));
        b.setStableRiskLevel(evaluation.getStableRiskLevel());
        b.setStableRiskLevelName(RiskLevels.findRiskLevelName(evaluation.getStableRiskLevel()));
        b.setStableEvaluationId(evaluation.getStableEvaluationId());
        return b;
    }

    private void fillEvaluationOfficeName(RiskDistrictStableRiskQueryBean b, String evaluationOffice) {
        if (StringUtils.isNumeric(evaluationOffice)) {
            try {
                long id = Long.parseLong(evaluationOffice);
                b.setEvaluationOfficeName(departDao.findDepartNameById(id));
            } catch (Exception e) {
            }
        }
    }

    @Override
    @Transactional
    public Integer updateDistrictRiskLevel(Long districtId) {
        RiskDistrict district = dao.getOne(districtId);
        Integer level = district.getRiskLevel();
        RiskDistrictEvaluation de = district.getRiskDistrictEvaluation();
        Set<RiskPoint> points = district.getRiskPoints();
        Integer newLevel = findNewLevel(de, points);
        // 加入风险校正
        if (de != null && de.getReviseLevel() != null) {
            List<Integer> levels = JSON.parseArray(de.getReviseLevel(), Integer.class);
            newLevel = calRiskLevel(newLevel, levels);
        }
        // 查找作业证中的最高级别，取三者的最高级别，作业证审核通过即可取其级别，一旦验收通过即舍弃
        Integer jobLevel = findJobLevel(districtId);

        logger.info("jobLevel=" + jobLevel);

        if (jobLevel != null) {
            newLevel = newLevel == null ? jobLevel : Math.min(jobLevel, newLevel);
        }
        district.setRiskLevel(newLevel);
        dao.save(district);
        // riskLevel越大，风险越低
        if (level != null && newLevel != null && level > newLevel) {
            //风险来源
            String riskSource = "区域风险评估";
            if (Objects.equals(newLevel, jobLevel)) {
                riskSource = "作业风险评估";
            }
            evaluationAlarmMessageService.createRiskLevelChangeMessage(districtId, null, newLevel, level, riskSource, "评估");
        }
        return newLevel;
    }

    @Override
    public ResultBean levelSpread() {
        List<RiskDistrict> all = dao.findAll();
        List<RiskDistrict> collect = all.stream().filter(r -> r.getRiskLevel() != null).collect(Collectors.toList());
        Map<Integer, Long> map = collect.stream().collect(Collectors.groupingBy(RiskDistrict::getRiskLevel, Collectors.counting()));
        List<RiskDistrictLevelSpreadDto> resultList = Lists.newArrayList();
        for (Integer integer : map.keySet()) {
            Long aLong = map.get(integer);
            resultList.add(new RiskDistrictLevelSpreadDto(RiskLevels.findRiskLevelName(integer), aLong));
        }
        return ResultBean.wrapSuccessfulResult(resultList);
    }

    /**
     * 风险区域列表
     *
     * @return
     */
    @Override
    public List<SimpleSelectListBean> getDistrictSimpleList() {
        List<RiskDistrict> all = dao.findAll();
        List<SimpleSelectListBean> list = new ArrayList<>();
        for (RiskDistrict district : all) {
            SimpleSelectListBean bean = new SimpleSelectListBean();
            bean.setValue(district.getId());
            bean.setLabel(district.getName());
            list.add(bean);
        }
        return list;
    }

    /**
     * 批量删除风险分区
     *
     * @param bean
     */
    @Override
    public void deleteByList(LongListBean bean) {
        if (bean != null && !CollectionUtils.isEmpty(bean.getIds())) {
            for (Long id : bean.getIds()) {
                try {
                    this.delete(id);
                } catch (ApiBusinessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public ResultBean riskAreaSum() {
        List<RiskDistrict> list = dao.findAll();
        List<BpWorkRiskDto> dtoList = BpWorkRiskDto.defaultDto();
        if (CollectionUtils.isEmpty(list)) {
            return ResultBean.success(dtoList);
        }
        RiskEvaluationControl control = controlDao.findByName("风险四色图计算逻辑");
        Map<String, Long> map = new HashMap<>();
        if (control != null && control.getSwitchState() == 0) {
            map = list.stream().filter(r -> r.getStableRiskLevel() != null).collect(Collectors.groupingBy(r ->
                    RiskLevels.findRiskLevelName(r.getStableRiskLevel()), Collectors.counting()));
        } else {
            map = list.stream().filter(r -> RiskLevels.getRealLevelIntValue(r.getRealTimeRiskLevel()) != null).collect(Collectors.groupingBy(r ->
                    RiskLevels.getRealLevelIntValueName(r.getRealTimeRiskLevel()), Collectors.counting()));
        }
        for (BpWorkRiskDto dto : dtoList) {
            Long aLong = map.get(dto.getName());
            if (aLong != null) {
                dto.setSum(aLong.intValue());
            }
        }
        return ResultBean.success(dtoList);
    }

    private Integer calRiskLevel(Integer newLevel, List<Integer> levels) {
        if (CollectionUtils.isEmpty(levels)) {
            return newLevel;
        }
        for (Integer level : levels) {
            if (level == 2) {
                newLevel -= 2;
            } else if (level == 3) {
                newLevel -= 4;
            } else if (level == 4) {
                newLevel -= 2;
            } else {
                newLevel -= 1;
            }
        }
        if (-13 <= newLevel && newLevel < 1) {
            return 1;
        }
        return newLevel;
    }

    private Integer findJobLevel(Long districtId) {
        return riskEvaluationRepoService.findMostImportWorkSafetyCertRiskLevelOfDistrict(districtId);
    }

    private Integer findNewLevel(RiskDistrictEvaluation de, Set<RiskPoint> points) {
        // 区域固有风险
        Integer stableRiskLevel = de == null ? null : de.getStableRiskLevel();
        // 区域控制风险
        Integer controlRiskLevel = null;
        for (RiskPoint p : points) {
            if (!RiskPointStates.isNormal(p.getState())) {
                // 跳过非正常状态的风险点
                continue;
            }
            // riskLevel越大，风险越低
            if (controlRiskLevel == null || (p.getRiskLevel() != null && p.getRiskLevel() < controlRiskLevel)) {
                // 只挑选
                controlRiskLevel = p.getRiskLevel();
            }
        }
        // 根据区域风险等级计算规则
        return RiskPointUtil.calculateDistrictRiskLevel(stableRiskLevel, controlRiskLevel);
    }

    @Override
    public List<BpBaseUserBean> getResponsibleAndHelpers(Long id) {
        Optional<RiskDistrict> districtOptional = dao.findById(id);
        List<BpBaseUserBean> list = new ArrayList<>();
        if (districtOptional.isPresent()) {
            RiskDistrict riskDistrict = districtOptional.get();
            String responsibleUser = riskDistrict.getResponsibleUser();
            //区域长（负责人）
            List<Long> responsibleUserList = JSONArray.parseArray(responsibleUser, Long.class);
            if (responsibleUserList != null && responsibleUserList.size() > 0) {
                for (Long aLong : responsibleUserList) {
                    Optional<BaseUser> byId = baseUserDao.findById(aLong);
                    if (byId.isPresent()) {
                        BaseUser baseUser = byId.get();
                        BpBaseUserBean bpBaseUserBean = new BpBaseUserBean();
                        bpBaseUserBean.setId(baseUser.getId());
                        bpBaseUserBean.setName(baseUser.getRealName());
                        list.add(bpBaseUserBean);
                    }
                }
            }
            String areaHelpers = riskDistrict.getAreaHelpers();
            //区域协助人员
            List<Long> helpersList = JSONArray.parseArray(areaHelpers, Long.class);
            if (helpersList != null && helpersList.size() > 0) {
                for (Long aLong : helpersList) {
                    if (responsibleUserList != null && responsibleUserList.contains(aLong))
                        continue;
                    Optional<BaseUser> byId = baseUserDao.findById(aLong);
                    if (byId.isPresent()) {
                        BaseUser baseUser = byId.get();
                        BpBaseUserBean bpBaseUserBean = new BpBaseUserBean();
                        bpBaseUserBean.setId(baseUser.getId());
                        bpBaseUserBean.setName(baseUser.getRealName());
                        list.add(bpBaseUserBean);
                    }
                }
            }
        }
        return list;
    }

}
